package com.payment.controller.payment;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.payment.entity.payment.wxscan.requset.RequestWeiXinScanPay;
import com.payment.entity.payment.wxscan.requset.RequestWeiXinScanPayData;
import com.payment.entity.payment.wxscan.requset.RequestWeiXinScanPayTradeData;
import com.payment.entity.payment.wxscan.response.ResponseWeiXinScanPay;
import com.payment.entity.payment.wxscan.response.ResponseWeiXinScanPayData;
import com.payment.entity.payment.wxscan.response.ResponseWeiXinScanPayTradeData;
import com.payment.service.SequenceService;
import com.payment.utils.MD5;
import com.payment.utils.UtilsInterfacesPackage;
import com.payment.utils.payment.WeiXinPayUtil;
import com.payment.utils.payment.WxPayConstants;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@RestController
@Api(description = "微信扫二维码支付")
/**
 * 1，微信扫二维码支付接口：
 *
 * 2，适用于新的客户：最新版的的领科 H5 和其他想要使用领科收款接口收款的（可以是客户自己的账号或者领科发账号）客户；
 *
 * 3，更新的数据表为：user_order_package_t，user_order_payment_t；
 *
 *  4，更新的数据库为：v-shop
 *
 * @author lm
 * @date 2019/11/06
 */

public class WeiXinScanPayController {
    private static Logger logger = Logger.getLogger(WeiXinScanPayController.class);
    @Autowired
    private SequenceService sequenceService;

    /***微信扫二维码支付接口
     *
     * @param requestWeiXinScanPay
     * @param request
     * @return
     * @throws Exception
     */
    @PostMapping(value = "/weixinScan", produces = "application/json;charset=utf-8")
    @CrossOrigin
    @ResponseBody
    @ApiOperation(value = "微信扫二维码支付下单", response = ResponseWeiXinScanPay.class)
    public String weixinScan(@ApiParam @RequestBody RequestWeiXinScanPay requestWeiXinScanPay, HttpServletRequest request) throws Exception {
        // 1，生成流水号
        String connSeqNo = sequenceService.getPackageTaskNo();
        // 2,生成当前时间戳
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String curtime = df.format(new Date());
        //3，定义回报报文
        String jsonString;
        UtilsInterfacesPackage utils = new UtilsInterfacesPackage();

        String requestStr = JSON.toJSONString(requestWeiXinScanPay);
        if (requestStr == null) {
            logger.info("请求报文不合法:requestStr为空");
            jsonString = utils.dataWeiKong(connSeqNo, curtime);
            return jsonString;
        } else {
            logger.info("前端请求报文是：" + requestStr);
            RequestWeiXinScanPay requestPackage = JSONArray.parseObject(requestStr, RequestWeiXinScanPay.class);
            String requestSign = requestPackage.getSign();
            if (requestSign == null) {
                logger.info("请求报文不合法:sign为空");
                jsonString = utils.dataWeiKong(connSeqNo, curtime);
                return jsonString;
            } else {
                System.out.println("请求的签名是：" + requestSign);
                RequestWeiXinScanPayData requestData = requestPackage.getData();
                if (requestData == null) {
                    logger.info("请求报文不合法:data为空");
                    jsonString = utils.dataWeiKong(connSeqNo, curtime);
                    return jsonString;
                } else {
                    String partnerCode = requestData.getPartnerCode();
                    String ConnSeqNo = requestData.getConnSeqNo();
                    String tradeTime = requestData.getTradeTime();
                    String tradeType = requestData.getTradeType();
                    String lang = requestData.getLang();
                    String version = requestData.getVersion();

                    RequestWeiXinScanPayTradeData requestTradeData = requestData.getTradeData();
                    if (requestTradeData == null || StringUtils.isBlank(partnerCode) || StringUtils.isBlank(ConnSeqNo) || StringUtils.isBlank(tradeTime) || StringUtils.isBlank(tradeType) || lang == null || version == null) {
                        logger.info("请求报文不合法:data参数不合法");
                        jsonString = utils.dataWeiKong(connSeqNo, curtime);
                        return jsonString;
                    } else {

                        String payAmount = requestTradeData.getPayAmount();
                        String payId = requestTradeData.getPayId();
                        String appid = requestTradeData.getAppid();
                        String mch_id = requestTradeData.getMch_id();
                        String body = requestTradeData.getBody();
                        String KEY = requestTradeData.getKey();

                        if (StringUtils.isBlank(payAmount) || StringUtils.isBlank(payId) || appid == null || mch_id == null || KEY == null) {
                            logger.info("请求报文不合法:APPID或者MCH_ID不可以为空！");
                            jsonString = utils.dataWeiKong(connSeqNo, curtime);
                            return jsonString;
                        } else {
                            // 将请求体json转成String
                            String str = JSON.toJSONString(requestData);
                            // 将Str拿去计算签名
                            String sign = utils.calculateSignature(str);
                            logger.info("计算的签名是：" + sign);
                            if (!requestSign.equalsIgnoreCase(sign)) {
                                logger.info("签名验证失败！");
                                jsonString = utils.signatureFailure(ConnSeqNo, tradeTime, partnerCode, tradeType);
                                return jsonString;
                            } else {

                                String prePayInfoXml = "";
                                // 获取ip地址:
                                String ipAddrStr = WeiXinPayUtil.getIp2(request);
                                boolean flag = WeiXinPayUtil.isInteger(payAmount);

                                if (StringUtils.isBlank(appid) || StringUtils.isBlank(mch_id) || StringUtils.isBlank(body) || StringUtils.isBlank(KEY)) {

                                    String appId = WxPayConstants.APPID;
                                    String mchId = WxPayConstants.MCH_ID;
                                    String bodys = WxPayConstants.body;
                                    String key = WxPayConstants.KEY;
                                    // 如果是整型
                                    if (flag == true) {
                                        int Amount = Integer.valueOf(payAmount).intValue();
                                        int totel_fee = Amount * 100;
                                        prePayInfoXml = WeiXinPayUtil.UnifiedOrderScan(payId, totel_fee, appId, mchId, bodys, key, ipAddrStr);
                                        logger.info("Controller中的prePayInfoXml：" + prePayInfoXml);


                                    } else {
                                        // DecimalFormat("#")表示float类型格式化时不要小数点了
                                        DecimalFormat decimalFormat = new DecimalFormat("#");
                                        float Amount = Float.parseFloat(payAmount);
                                        int totel_fee = Integer.parseInt(decimalFormat.format(Amount * 100));
                                        prePayInfoXml = WeiXinPayUtil.UnifiedOrderScan(payId, totel_fee, appId, mchId, bodys, key, ipAddrStr);
                                        logger.info("Controller的prePayInfoXml：" + prePayInfoXml);

                                    }
                                } else {
                                    // 如果是整型
                                    if (flag == true) {
                                        int Amount = Integer.valueOf(payAmount).intValue();
                                        int totel_fee = Amount * 100;
                                        prePayInfoXml = WeiXinPayUtil.UnifiedOrderScan(payId, totel_fee, appid, mch_id, body, KEY, ipAddrStr);
                                        logger.info("Controller中的prePayInfoXml：" + prePayInfoXml);


                                    } else {
                                        // DecimalFormat("#")表示float类型格式化时不要小数点了
                                        DecimalFormat decimalFormat = new DecimalFormat("#");
                                        float Amount = Float.parseFloat(payAmount);
                                        int totel_fee = Integer.parseInt(decimalFormat.format(Amount * 100));
                                        prePayInfoXml = WeiXinPayUtil.UnifiedOrderScan(payId, totel_fee, appid, mch_id, body, KEY, ipAddrStr);
                                        logger.info("Controller中的prePayInfoXml：" + prePayInfoXml);

                                    }

                                }
                                Map<String, Object> map = new HashMap<String, Object>();
                                map = WeiXinPayUtil.getPayScanMap(prePayInfoXml);
                                logger.info("Controller中的map：" + map);

                                String result_code = (String) map.get("result_code");
                                String return_code = (String) map.get("return_code");

                                if ("SUCCESS".equals(result_code) && "SUCCESS".equals(return_code)) {
                                    String prepay_id = (String) map.get("prepay_id");
                                    String trade_type = (String) map.get("trade_type");
                                    String code_url = (String) map.get("code_url");

                                    if (StringUtils.isBlank(prepay_id) || StringUtils.isBlank(trade_type) || StringUtils.isBlank(code_url)) {
                                        logger.info("微信H5下单出现问题");
                                        jsonString = utils.unknownError(connSeqNo, curtime, tradeType);
                                        return jsonString;
                                    } else {
                                        //回报报文TradeData
                                        ResponseWeiXinScanPayTradeData tradeData = new ResponseWeiXinScanPayTradeData();
                                        tradeData.setCode_url(code_url);
                                        tradeData.setPrepay_id(prepay_id);
                                        tradeData.setTrade_type(trade_type);
                                        tradeData.setPayId(payId);
                                        //回报Data
                                        ResponseWeiXinScanPayData data = new ResponseWeiXinScanPayData();
                                        data.setConnSeqNo(ConnSeqNo);
                                        data.setPartnerCode(partnerCode);
                                        data.setTradeType(tradeType);
                                        data.setTradeTime(tradeTime);
                                        data.setTradeRstCode("0000");
                                        if (lang.equals("cn") || StringUtils.isBlank(lang)) {
                                            data.setTradeRstMessage("成功");
                                        } else {
                                            data.setTradeRstMessage("success");
                                        }
                                        data.setTradeData(tradeData);

                                        ResponseWeiXinScanPay responseWeiXinPay = new ResponseWeiXinScanPay();
                                        responseWeiXinPay.setData(data);
                                        responseWeiXinPay.setSign(MD5.calcMD5(JSON.toJSONString(data)));
                                        // 返回给调用者的报文
                                        jsonString = JSON.toJSONString(responseWeiXinPay);
                                        logger.info("响应报文：" + jsonString);
                                        return jsonString;

                                    }
                                } else {

                                    logger.info("下单失败");
                                    jsonString = utils.unknownError(connSeqNo, curtime, tradeType);
                                    return jsonString;

                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

